#ifndef __TOYM__BASE__FIXED_BUFFER_H__
#define __TOYM__BASE__FIXED_BUFFER_H__

#include <array>
#include <cassert>
#include <memory>
#include <vector>
#include <cstring>

namespace toym {

template<std::size_t Size = 4UL*1024UL*1024UL>
class FixedBuffer {
public:
    FixedBuffer()
        :m_buf(),
         m_used(0UL)
    {}

    // 当前已经使用的空间
    std::size_t used() const {
        return m_used;
    }

    // 剩余的可用空间
    std::size_t availableSize() const {
        return Size - m_used;
    }

    // 追加数据
    void append(const char* buf) {
        std::size_t appendSize = 0;
        std::size_t avail = availableSize();
        for (; buf[appendSize] != '\0' && appendSize < avail; ++appendSize) {
            m_buf[m_used++] = buf[appendSize];
        }
    }

    void clear() {
        m_used = 0UL;
    }

    void append(const char* buf, std::size_t sz) {
        std::memmove(m_buf.data() + m_used, buf, std::min(sz, availableSize()));
        m_used = std::min(Size, m_used + sz);
    }

    void append(char c) {
        if (availableSize() > 0) 
            m_buf[m_used++] = c;

    }

    char* data() {
        return m_buf.data();
    }

private:
    std::array<char, Size> m_buf;
    std::size_t m_used;
};

using LargeBuffer = FixedBuffer<>;
using BufferPtr = std::unique_ptr<LargeBuffer>;
using BufferVertor = std::vector<BufferPtr>;

using SmallBuffer = FixedBuffer<4UL*1024UL>;

}; // namespace toym



#endif